﻿using System;
using System.Text;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace SocketLib
{
	public class Server
	{

		private byte[] buff = new byte[1024 * 10]; //缓冲区64K

		//private byte[] tempbuff = new byte[(1024 * 80 + 12)*2]; //缓冲区64K
		Queue<byte[]> bufferPool = new Queue<byte[]>();
		int i = 0;
		private ArrayList tempArr = new ArrayList();


		public ConnectionList Connections = new ConnectionList();


		#region 事件委托
		public delegate void CallbackDelegate(object sender, CallbackEventArgs e);
		public event CallbackDelegate Callback_EventHandler;

		public delegate void Accept_Delegate(object sender, Accept_EventArgs e);
		public event Accept_Delegate Accept_EventHandler;

		public delegate void Closed_Delegate(object sender, Closed_EventArgs e);
		public event Closed_Delegate Closed_EventHandler;


		public class CallbackEventArgs : EventArgs
		{
			//public IPMPack pack { get; set; }
			public byte[] buffer { get; set; }

		}

		public class Accept_EventArgs : EventArgs
		{
			public string ip { get; set; }
		}

		public class Closed_EventArgs : EventArgs
		{
			public Socket socket { get; set; }
		}

		#endregion

		public void Start()
		{
			Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			socket.Bind(new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], 3451));
			socket.Listen(10);
			socket.BeginAccept(new AsyncCallback(AcceptCallback), socket);
            


			//启动完毕。。

			//ThreadPool.QueueUserWorkItem(new WaitCallback(AnalysisbufferPool5));

		}


		public void AcceptCallback(IAsyncResult ar)
		{

			Socket s = (Socket)ar.AsyncState;
			Socket TcpSocket = s.EndAccept(ar);

			Connections.Add(new Connection(TcpSocket));


			if (Accept_EventHandler != null)
			{
				Accept_EventArgs args = new Accept_EventArgs();
				args.ip = TcpSocket.RemoteEndPoint.ToString();

				Accept_EventHandler(this, args);
			}


			TcpSocket.BeginReceive(buff, 0, buff.Length, SocketFlags.None, new AsyncCallback(Read_Callback2), TcpSocket);

			//TcpSocket.RemoteEndPoint.ToString() + "建立连接";

		}


		private void Disconnect(Socket sc)
		{
			if (Closed_EventHandler != null)
			{
				Closed_EventArgs args = new Closed_EventArgs();
				args.socket = sc;
				Closed_EventHandler(this, args);
			}
		}

		public void Read_Callback(IAsyncResult ar)
		{
			Socket client = (Socket)ar.AsyncState;
			int revCount = client.EndReceive(ar);
			//int a = client.Available;

			if (revCount > 0)
			{
				if (tempArr.Count == 0)
				{


					int packSize = BitConverter.ToInt32(buff, 0);

					//一个包没接收完整 放到缓存区
					if (revCount < packSize)
					{
						Byte[] a = new Byte[revCount];
						Buffer.BlockCopy(buff, 0, a, 0, revCount);
						tempArr.AddRange(a);


					}

					//接收多了把多的放到缓存区
					if (revCount > packSize)
					{
						Byte[] a = new Byte[revCount - packSize];
						Buffer.BlockCopy(buff, packSize, a, 0, revCount - packSize);
						tempArr.AddRange(a);

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[packSize];
							Buffer.BlockCopy(buff, packSize, ss, 0, packSize);

							args.buffer = ss;
							Callback_EventHandler(this, args);
						}
					}
					if (revCount == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[revCount];
							Buffer.BlockCopy(buff, 0, ss, 0, revCount);

							args.buffer = ss;
							Callback_EventHandler(this, args);
						}
					}

					//刚好接收完毕
				}
				else //end  tempbuff.Length == 0
				{
					byte[] a = (byte[])tempArr.ToArray(typeof(Byte));

					int packSize = BitConverter.ToInt32(a, 0);


					byte[] b = new byte[revCount];
					Buffer.BlockCopy(buff, 0, b, 0, revCount);
					tempArr.AddRange(b);



					if (a.Length + revCount == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							Byte[] f = (byte[])tempArr.ToArray(typeof(Byte));

							args.buffer = f;
							Callback_EventHandler(this, args);
						}
						tempArr.Clear();

					}

					//多了
					if (a.Length + revCount > packSize)
					{


						Byte[] c = new Byte[packSize];
						Byte[] d = (byte[])tempArr.ToArray(typeof(Byte));
						Byte[] e = new byte[d.Length - packSize];

						Buffer.BlockCopy(d, 0, c, 0, packSize);
						Buffer.BlockCopy(d, packSize, e, 0, d.Length - packSize);
						tempArr.Clear();
						tempArr.AddRange(e);

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();
							args.buffer = c;
							Callback_EventHandler(this, args);
						}


					}

				}




				//if (CallbackEventHandler != null)
				//{
				//    CallbackEventArgs args = new CallbackEventArgs();
				//    //IPMPack pack = new IPMPack();
				//    //pack.unpacked(buff, 0, revCount);

				//    args.buffer = buff;
				//    CallbackEventHandler(this, args);
				//}

				client.BeginReceive(buff, 0, buff.Length, SocketFlags.None, new AsyncCallback(Read_Callback), client);


			}


		}

		public void Read_Callback2(IAsyncResult ar)
		{

			
			Socket client = (Socket)ar.AsyncState;
			try
			{

				int revCount = client.EndReceive(ar);

				//int a = client.Available;

				if (revCount > 0)
				{
					Byte[] a = new Byte[revCount];
					Buffer.BlockCopy(buff, 0, a, 0, revCount);
					bufferPool.Enqueue(a);
				}
                AnalysisbufferPool5(null);
				client.BeginReceive(buff, 0, buff.Length, SocketFlags.None, new AsyncCallback(Read_Callback2), client);

			}
			catch (SocketException ex)
			{
				if (ex.ErrorCode == 10054)
				{
					Disconnect(client);
					
				}
			}
			finally
			{

			}

		}


		public void AnalysisbufferPool2(object o)
		{
			MemoryStream mem = new MemoryStream();

			while (true)
			{
				if (bufferPool.Count == 0)
					continue;

				if (mem.Length == 0)
				{

					byte[] b1 = bufferPool.Dequeue();
					int packSize = BitConverter.ToInt32(b1, 0);

					//一个包没接收完整 放到缓存区
					if (b1.Length < packSize)
					{
						mem.Write(b1, 0, b1.Length);

					}

					//接收多了把多的放到缓存区
					if (b1.Length > packSize)
					{
						Byte[] a = new Byte[b1.Length - packSize];
						Buffer.BlockCopy(b1, packSize, a, 0, b1.Length - packSize);
						mem.Write(a, 0, a.Length);

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[packSize];
							Buffer.BlockCopy(b1, packSize, ss, 0, packSize);

							args.buffer = ss;
							Callback_EventHandler(this, args);
						}
					}
					if (b1.Length == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[b1.Length];
							Buffer.BlockCopy(b1, 0, ss, 0, b1.Length);

							args.buffer = ss;
							Callback_EventHandler(this, args);
						}
					}

					//刚好接收完毕
				}
				else //end  tempbuff.Length == 0
				{



					byte[] b = bufferPool.Dequeue();

					mem.Write(b, 0, b.Length);

					byte[] a = mem.ToArray();

					int packSize = BitConverter.ToInt32(a, 0);


					if (a.Length == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							args.buffer = a;
							Callback_EventHandler(this, args);
						}
						mem = new MemoryStream();
					}

					//多了
					if (a.Length > packSize)
					{


						Byte[] c = new Byte[packSize];
						Byte[] d = mem.ToArray();
						Byte[] e = new byte[d.Length - packSize];

						Buffer.BlockCopy(d, 0, c, 0, packSize);
						Buffer.BlockCopy(d, packSize, e, 0, d.Length - packSize);

						//mem.SetLength(0);
						mem = new MemoryStream();


						mem.Write(e, 0, e.Length);

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();
							args.buffer = c;
							Callback_EventHandler(this, args);
						}


					}



				}// end else



			}
		}

		public void AnalysisbufferPool3(object o)
		{

			byte[] temp = null;

			while (true)
			{
				if (bufferPool.Count == 0)
					continue;

				//DateTime dt1 = DateTime.Now;

				if (temp == null)
				{

					byte[] b1 = bufferPool.Dequeue();
					int packSize = BitConverter.ToInt32(b1, 0);

					//一个包没接收完整 放到缓存区
					if (b1.Length < packSize)
					{
						temp = b1;
					}

					//接收多了把多的放到缓存区
					if (b1.Length > packSize)
					{
						Byte[] a = new Byte[b1.Length - packSize];
						Buffer.BlockCopy(b1, packSize, a, 0, b1.Length - packSize);
						temp = a;

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[packSize];
							Buffer.BlockCopy(b1, 0, ss, 0, packSize);

							args.buffer = ss;
							Callback_EventHandler(this, args);
							//DateTime dt2 = DateTime.Now;
							//Console.WriteLine("分析:" + (dt2 - dt1).Milliseconds.ToString());

						}
					}
					if (b1.Length == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[b1.Length];
							Buffer.BlockCopy(b1, 0, ss, 0, b1.Length);

							args.buffer = ss;
							Callback_EventHandler(this, args);
							//DateTime dt2 = DateTime.Now;
							//Console.WriteLine("分析:" + (dt2 - dt1).Milliseconds.ToString());

						}
					}//刚好接收完毕


				}
				else //end  tempbuff.Length == 0
				{



					byte[] b = bufferPool.Dequeue();

					temp = MergeBytes(temp, b);


					int packSize = BitConverter.ToInt32(temp, 0);


					if (temp.Length == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							args.buffer = temp;
							Callback_EventHandler(this, args);
							//DateTime dt2 = DateTime.Now;
							//Console.WriteLine("分析:" + (dt2 - dt1).Milliseconds.ToString());

						}
						temp = null;
					}

					//多了
					if (temp.Length > packSize)
					{


						Byte[] c = new Byte[packSize];
						Byte[] d = temp;
						Byte[] e = new byte[d.Length - packSize];

						Buffer.BlockCopy(d, 0, c, 0, packSize);
						Buffer.BlockCopy(temp, packSize, e, 0, temp.Length - packSize);

						temp = e;


						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();
							args.buffer = c;
							Callback_EventHandler(this, args);
							//DateTime dt2 = DateTime.Now;
							//Console.WriteLine("分析:" + (dt2 - dt1).Milliseconds.ToString());

						}


					}



				}// end else


			}
		}


		public void AnalysisbufferPool4(object o)
		{
			int charLen = 0; //定义每次解包返回的字符长度

			int parseBytesCount = 0;  //定义已解包的字节数

			int LenghHeader = 0; //定义收到包的长度

			bool needReadLengthHeader = true; //是否需要读取长度的头

			int srcOffSet = 0; //定义要解析的数据块的偏移量

			byte[] tempBuffer = null;

			while (true)
			{
				if (bufferPool.Count == 0)
					continue;


				if (tempBuffer == null)
				{
					byte[] b1 = bufferPool.Dequeue();

					if (needReadLengthHeader)
					{
						LenghHeader = BitConverter.ToInt32(b1, 0);
						needReadLengthHeader = false;
						srcOffSet = 4;
					}

					//一个包没接收完整 放到缓存区
					if (b1.Length < LenghHeader)
					{
						tempBuffer = b1;
					}

					//接收多了把多的放到缓存区
					while (b1.Length > LenghHeader)
					{
						Byte[] a = new Byte[b1.Length - LenghHeader];
						Buffer.BlockCopy(b1, LenghHeader, a, 0, b1.Length - LenghHeader);
						tempBuffer = a;

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[LenghHeader];
							Buffer.BlockCopy(b1, 0, ss, 0, LenghHeader);

							args.buffer = ss;
							Callback_EventHandler(this, args);

						}
					}
					if (b1.Length == LenghHeader)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[b1.Length];
							Buffer.BlockCopy(b1, 0, ss, 0, b1.Length);
							args.buffer = ss;
							Callback_EventHandler(this, args);
						}
					}//刚好接收完毕


				}
				else //end  tempbuff.Length == 0
				{



					byte[] b = bufferPool.Dequeue();

					tempBuffer = MergeBytes(tempBuffer, b);


					LenghHeader = BitConverter.ToInt32(tempBuffer, 0);


					if (tempBuffer.Length == LenghHeader)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							args.buffer = tempBuffer;
							Callback_EventHandler(this, args);

						}
						tempBuffer = null;
					}

					//多了
					while (tempBuffer.Length > LenghHeader)
					{


						Byte[] c = new Byte[LenghHeader];
						Byte[] d = tempBuffer;
						Byte[] e = new byte[d.Length - LenghHeader];

						Buffer.BlockCopy(d, 0, c, 0, LenghHeader);
						Buffer.BlockCopy(tempBuffer, LenghHeader, e, 0, tempBuffer.Length - LenghHeader);

						tempBuffer = e;


						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();
							args.buffer = c;
							Callback_EventHandler(this, args);
						}


					}



				}// end else


			}
		}


		/// <summary>
		/// 目前这个解析最快
		/// </summary>
		/// <param name="o"></param>
		public void AnalysisbufferPool5(object o)
		{

			int LenghHeader = 0; //定义收到包的长度

			bool needReadLengthHeader = true; //是否需要读取长度的头


			byte[] tempBuffer = null;

			while (true)
			{
				if (bufferPool.Count == 0)
					continue;

				byte[] b1 = bufferPool.Dequeue();

				tempBuffer = MergeBytes(tempBuffer, b1);


				if (needReadLengthHeader)
				{
					LenghHeader = BitConverter.ToInt32(tempBuffer, 0);
					needReadLengthHeader = false;

				}


				//接收多了把多的放到缓存区
				if (tempBuffer.Length >= LenghHeader)
				{

					needReadLengthHeader = true;


					Byte[] a = new Byte[tempBuffer.Length - LenghHeader];
					Buffer.BlockCopy(tempBuffer, LenghHeader, a, 0, tempBuffer.Length - LenghHeader);

					//把完整的包发过去处理
					if (Callback_EventHandler != null)
					{
						CallbackEventArgs args = new CallbackEventArgs();
						byte[] ss = new byte[LenghHeader];
						Buffer.BlockCopy(tempBuffer, 0, ss, 0, LenghHeader);
						args.buffer = ss;
						Callback_EventHandler(this, args);
					}
					tempBuffer = a;
					///TODO:如果这个是最后一个包 没发啊 
					if (bufferPool.Count == 0 && tempBuffer.Length > 0)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();
							args.buffer = tempBuffer;
							Callback_EventHandler(this, args);
						}
						tempBuffer = null;
					}



				}


			}
		}


		public void AnalysisbufferPool(object o)
		{
			ArrayList templist = new ArrayList();

			while (true)
			{
				if (bufferPool.Count == 0)
					continue;
				//byte[] b1= bufferPool.Dequeue();
				//int packSize = BitConverter.ToInt32(b1, 0);

				////一个包没接收完整 放到缓存区
				//if (b1.Length < packSize)
				//{
				//    byte[] b2= bufferPool.Dequeue();
				//    tempArr.AddRange(b2);
				//}

				if (templist.Count == 0)
				{

					byte[] b1 = bufferPool.Dequeue();
					int packSize = BitConverter.ToInt32(b1, 0);

					//一个包没接收完整 放到缓存区
					if (b1.Length < packSize)
					{
						templist.AddRange(b1);

					}

					//接收多了把多的放到缓存区
					if (b1.Length > packSize)
					{
						Byte[] a = new Byte[b1.Length - packSize];
						Buffer.BlockCopy(b1, packSize, a, 0, b1.Length - packSize);
						templist.AddRange(a);

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[packSize];
							Buffer.BlockCopy(b1, packSize, ss, 0, packSize);

							args.buffer = ss;
							Callback_EventHandler(this, args);
						}
					}
					if (b1.Length == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							byte[] ss = new byte[b1.Length];
							Buffer.BlockCopy(b1, 0, ss, 0, b1.Length);

							args.buffer = ss;
							Callback_EventHandler(this, args);
						}
					}

					//刚好接收完毕
				}
				else //end  tempbuff.Length == 0
				{



					byte[] b = bufferPool.Dequeue();

					templist.AddRange(b);
					byte[] a = (byte[])templist.ToArray(typeof(Byte));

					int packSize = BitConverter.ToInt32(a, 0);


					if (a.Length == packSize)
					{
						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();

							Byte[] f = (byte[])templist.ToArray(typeof(Byte));

							args.buffer = f;
							Callback_EventHandler(this, args);
						}
						templist.Clear();

					}

					//多了
					if (a.Length > packSize)
					{


						Byte[] c = new Byte[packSize];
						Byte[] d = (byte[])templist.ToArray(typeof(Byte));
						Byte[] e = new byte[d.Length - packSize];

						Buffer.BlockCopy(d, 0, c, 0, packSize);
						Buffer.BlockCopy(d, packSize, e, 0, d.Length - packSize);
						templist.Clear();
						templist.AddRange(e);

						//把完整的包发过去处理

						if (Callback_EventHandler != null)
						{
							CallbackEventArgs args = new CallbackEventArgs();
							args.buffer = c;
							Callback_EventHandler(this, args);
						}


					}



				}



			}
		}



		public byte[] MergeBytes(byte[] pByteA, byte[] pByteB)
		{
			if (pByteA == null || pByteA.Length == 0)
			{
				return pByteB;
			}
			else
			{

				MemoryStream ms = new MemoryStream();
				ms.Write(pByteA, 0, pByteA.Length);
				ms.Write(pByteB, 0, pByteB.Length);


				//return ms.GetBuffer();
				return ms.ToArray();
			}
		}






		public void Send(string msg)
		{





			byte[] data = Encoding.Default.GetBytes(msg);
			IPMPack pack = new IPMPack();
			pack.PackType = 1;
			//pack.PackSize = data.Length;
			pack.PackNo = 10000;
			pack.Data = data;

			byte[] sendBuff = pack.Packed();

			Connections[0].ClientSocket.Send(sendBuff);
			//Connections[0].ClientSocket.Send(System.Text.Encoding.ASCII.GetBytes(msg));


		}

	}
}
